package com.stox.shared.indicator.model;

import java.util.Date;

import org.springframework.stereotype.Component;

import com.stox.shared.indicator.model.config.BaseIndicatorConfig;
import com.stox.shared.indicator.model.enumeration.IndicatorDisplayType;
import com.stox.shared.indicator.model.enumeration.IndicatorPosition;

@Component
public class SimpleMovingAverage extends AbstractIndicator<Double, BaseIndicatorConfig> {

	public SimpleMovingAverage() {
		super("SMA");
	}

	@Override
	public IndicatorDisplayType getDisplayType(final BaseIndicatorConfig config) {
		return IndicatorPosition.INDEPENDENT.equals(getPosition(config)) ? IndicatorDisplayType.AREA : IndicatorDisplayType.LINE;
	}

	@Override
	public IndicatorPosition getPosition(final BaseIndicatorConfig config) {
		switch (config.getBarValue()) {
			case VOLUME:
				return IndicatorPosition.OVERLAY_VOLUME;
			case SPREAD:
				return IndicatorPosition.INDEPENDENT;
			default:
				return IndicatorPosition.OVERLAY_PRICE;
		}
	}

	@Override
	public Value<Double> getValue(final BaseIndicatorConfig configuration, final Value<Double>[] in, final int index) throws UnsupportedOperationException {
		double sum = 0;
		final int span = configuration.getSpan();
		Date date = null;
		for (int i = index; i < (index + span); i++) {
			final Value<Double> value = in[index];
			sum += value.getValue();
			date = value.getDate();
		}
		return new Value<Double>(sum / span, date);
	}

	@Override
	@SuppressWarnings("unchecked")
	public Value<Double>[] getValues(final BaseIndicatorConfig configuration, final Value<Double>[] values) throws UnsupportedOperationException {
		final Value<Double>[] result = new Value[values.length];
		double sum = 0;
		final int span = configuration.getSpan();
		final int size = values.length;
		for (int i = size - 1; i >= 0; i--) {
			if (null == values[i]) {
				continue;
			}
			sum += values[i].getValue();
			if (i > (size - 1 - span)) {
				continue;
			}
			if (null == values[i + span]) {
				continue;
			}
			sum -= values[i + span].getValue();
			result[i] = new Value<Double>(sum / span, values[i].getDate());
		}
		return result;
	}

	@Override
	public BaseIndicatorConfig createDefaultConfiguration() {
		return new BaseIndicatorConfig();
	}

}
